home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacWorld 1999 July
/
Macworld (1999-07).dmg
/
Shareware World
/
Comms & Internet
/
HTML and CSS modes
/
HTML and CSS Modes
/
htmlElems.tcl
< prev
next >
Wrap
Text File
|
1999-04-24
|
42KB
|
1,409 lines
## -*-Tcl-*-
# ###################################################################
# HTML mode - tools for editing HTML documents
#
# FILE: "htmlElems.tcl"
# created: 96-04-29 21.31.14
# last update: 99-04-24 13.18.54
# Author: Johan Linde
# E-mail: <jlinde@telia.com>
# www: <http://www.theophys.kth.se/~jl/Alpha.html>
#
# Version: 2.1.4
#
# Copyright 1996-1999 by Johan Linde
#
# This software may be used freely, and distributed freely, as long as the
# receiver is not obligated in any way by receiving it.
#
# If you make improvements to this file, please share them!
#
# ###################################################################
##
proc htmlElems.tcl {} {}
#
# <P>
#
proc htmlElemParagraph {{attr ""}} {
global HTMLmodeVars
if {$HTMLmodeVars(pIsContainer)} {
htmlTag "htmlBuildCR2Elem P $attr"
} else {
htmlTag "htmlBuildOpening P 1 1 $attr"
}
}
# Insert a <BR> in the end of every line in selection.
proc htmlInsertLineBreaks {} {
if {![isSelection]} {
beep
message "No selection."
return
}
regsub -all "\r" [getSelect] "[htmlSetCase <BR>]\r" text
replaceText [getPos] [selEnd] $text
}
# Remove all <BR> in selection.
proc htmlRemoveLineBreaks {} {
if {![isSelection]} {
beep
message "No selection."
return
}
regsub -all -nocase "<BR(\[ \t\r\]+\[^<>\]*>|>)" [getSelect] "" text
if {$text != [getSelect]} {
replaceText [getPos] [selEnd] $text
}
}
# Insert <P> at empty lines in selection, and in the beginning of the selection.
# Several empty lines are contracted to one.
proc htmlInsertParagraphs {} {
global HTMLmodeVars
if {![isSelection]} {
beep
message "No selection."
return
}
set pIsContainer $HTMLmodeVars(pIsContainer)
if {[set oelem [htmlOpenElem P "" 0]] == ""} {return}
set pind [set indent [htmlFindNextIndent]]
if {$HTMLmodeVars(indentP)} {set pind [htmlIncreaseIndent $pind]}
set text "$indent\r$indent$oelem\r"
set prevLineEmpty 1
foreach ln [split [string trimright [string trimleft [getSelect] "\r"]] "\r"] {
regexp {[ \t]*} $ln lntest
# Only add <P> if previous line was not empty.
if {$ln == $lntest && !$prevLineEmpty} {
set prevLineEmpty 1
if {$pIsContainer} {
append text "$indent[htmlCloseElem P]\r$indent\r$indent$oelem\r"
} else {
append text "\r$indent$oelem\r"
}
} else {
# Skip an empty line which follows another empty line.
if {$ln != $lntest} {
set prevLineEmpty 0
append text "$pind[string trim $ln]\r"
}
}
}
if {$pIsContainer} {
append text "$indent[htmlCloseElem P][htmlCloseCR2 $indent [selEnd]]"
}
replaceText [getPos] [selEnd] $text
}
# Ask for input how to build a list. Returns "number of items" and
# "ask for list item attributes". Returns "" if canceled or any problem.
proc htmlListQuestions {ltype liattr lipr} {
global HTMLmodeVars
set promptNoisily $HTMLmodeVars(promptNoisily)
if {[string length $liattr]} {
set usedatts [htmlGetUsed $liattr]
} else {
set usedatts [htmlGetUsed LI]
}
if {$lipr != "LI"} {
set usedatts [concat $usedatts [htmlGetUsed DD]]
}
if {$HTMLmodeVars(useBigWindows)} {
set it {0 0 3 0}
while {1} {
set txt "dialog -w 280 -h 130 -b OK 20 100 85 120 -b Cancel 110 100 175 120 \
-t {$ltype list} 100 10 250 30 \
-t {How many items?} 10 40 150 60 -e [list [lindex $it 2]] 160 40 180 55"
if {[llength $usedatts]} {
append txt " -c {Ask for attributes for each $lipr} [lindex $it 3] \
10 70 330 85"
}
set it [eval $txt]
if {[lindex $it 1]} {return}
set items [lindex $it 2]
if {[llength $it] == 4 && [lindex $it 3]} {
set askForLiAttr 1
} else {
set askForLiAttr 0
}
if {![is::UnsignedInteger $items] && $ltype != "DL"} {
alertnote "Invalid input: non-negative integer required"
} elseif {![is::PositiveInteger $items] && $ltype == "DL"} {
alertnote "Invalid input: positive integer required"
} else {
break
}
}
} else {
if {$promptNoisily} {beep}
while {[catch {statusPrompt "$ltype list: How many items? " htmlNumberStatusFunc} items]} {
if {$items == "Cancel all!"} {message "Cancel"; return}
}
if {![is::UnsignedInteger $items] && $ltype != "DL"} {
beep; message "Invalid input: non-negative integer required."; return
} elseif {![is::PositiveInteger $items] && $ltype == "DL"} {
beep; message "Invalid input: positive integer required."; return
}
if {[llength $usedatts] && $items} {
if {$promptNoisily} {beep}
while {[catch {statusPrompt "Ask for attributes for each $lipr? \[n\] " \
htmlStatusAskYesOrNo} v]} {
if {$v == "Cancel all!"} {message "Cancel"; return}
}
if {$v == "yes"} {
set askForLiAttr 1
} else {
set askForLiAttr 0
}
} else {
set askForLiAttr 0
}
}
return [list $items $askForLiAttr]
}
# Lists: Puts <cr>s before and after a list, inserts <li>, leaves the
# insertion point there. If anything is selected, makes it the first item.
proc htmlBuildList {ltype {liattr ""} {listattr ""}} {
global HTMLmodeVars
global htmlCurSel
global htmlIsSel elecStopMarker
# Discursive list?
if {$ltype == "DL"} {htmlDiscursive; return}
set useTabMarks $HTMLmodeVars(useTabMarks)
set containers $HTMLmodeVars(lidtAreContainers)
set listStr [htmlListQuestions $ltype $liattr LI]
if {![llength $listStr]} {
return
} else {
set items [lindex $listStr 0]
set askForLiAttr [lindex $listStr 1]
}
# If zero list items, just make an htmlBuildCR2Elem
if {$items == 0} {
htmlBuildCR2Elem $ltype $listattr
return
}
htmlGetSel
set sel $htmlCurSel
set indent [htmlFindNextIndent]
set exind $indent
if {$HTMLmodeVars(indent${ltype})} {
set exind [htmlIncreaseIndent $exind]
htmlIndentChunk sel
}
set IsSel $htmlIsSel
set text [htmlOpenCR $indent 1]
if {$containers} {
if {[set text1 "[htmlOpenElem $ltype $listattr 0]\r"] == "\r"} {return}
append text $text1
if {$askForLiAttr} {
set text1 [htmlOpenElem LI $liattr 0]
} else {
set text1 [htmlSetCase <LI>]
}
if {$text1 == ""} {return}
append text $exind $text1
if {$IsSel} {
append text "${sel}[htmlCloseElem LI]"
set currpos [expr [getPos] + [string length $text]]
} else {
set currpos [expr [getPos] + [string length $text]]
append text [htmlCloseElem LI]
}
for {set i 1} {$i < $items} {incr i} {
append text "\r"
if {$askForLiAttr} {
set text1 [htmlOpenElem LI $liattr 0]
} else {
set text1 [htmlSetCase <LI>]
}
if {$text1 == ""} {return}
append text $exind $text1
if {$i == 1 && $IsSel} {
set currpos [expr [getPos] + [string length $text]]
} elseif {$useTabMarks} {
append text $elecStopMarker
}
append text [htmlCloseElem LI]
}
} else {
if {[set text1 [htmlOpenElem $ltype $listattr 0]] == ""} {return}
append text $text1
append text "\r"
if {$askForLiAttr} {
set text1 [htmlOpenElem LI $liattr 0]
} else {
set text1 [htmlSetCase <LI>]
}
if {$text1 == ""} {return}
append text $exind $text1
if {$IsSel} {
append text $sel
}
set currpos [expr [getPos] + [string length $text]]
for {set i 1} {$i < $items} {incr i} {
append text "\r"
if {$askForLiAttr} {
set text1 [htmlOpenElem LI $liattr 0]
} else {
set text1 [htmlSetCase <LI>]
}
if {$text1 == ""} {return}
append text $exind $text1
if {$useTabMarks} {append text $elecStopMarker}
}
}
append text "\r$indent[htmlCloseElem $ltype]"
append text [htmlCloseCR2 $indent [getPos]]
if {$useTabMarks} {append text $elecStopMarker}
if {$IsSel} { deleteSelection }
insertText $text
goto $currpos
}
# Add list entry. If there is a selection, make it the entry.
proc htmlBuildListEntry {liattr} {
global htmlCurSel htmlIsSel HTMLmodeVars elecStopMarker
set containers $HTMLmodeVars(lidtAreContainers)
set useTabMarks $HTMLmodeVars(useTabMarks)
htmlGetSel
set sel $htmlCurSel
set isSel $htmlIsSel
set indent [htmlFindNextIndent]
set text [htmlOpenCR $indent]
if {[set text1 [htmlOpenElem LI $liattr 0]] == ""} {return}
append text $text1
if {$isSel} { deleteSelection }
if {$containers} {
if {$isSel} {
insertText $text "${sel}" [htmlCloseElem LI]
} else {
set currpos [expr [getPos] + [string length $text]]
append text [htmlCloseElem LI]
if {$useTabMarks} { append text $elecStopMarker}
insertText $text
goto $currpos
}
} else {
insertText $text $sel
}
}
# Make list items from selection.
proc htmlMakeList {} {
global HTMLmodeVars htmlHideDeprecated
set isContainer $HTMLmodeVars(lidtAreContainers)
if {![isSelection]} {
beep
message "No selection."
return
}
if {$htmlHideDeprecated || $HTMLmodeVars(hideDeprecated)} {
set men {UL UL OL None}
} else {
set men {UL UL OL DIR MENU None}
}
set values [dialog -w 220 -h 130 -t "Make list" 50 10 210 30 \
-t "Each item begins with:" 10 40 160 55 -e "*" 170 40 200 55 \
-t "List:" 10 65 50 85 -m $men 55 65 200 85 \
-b OK 20 100 85 120 -b Cancel 105 100 170 120]
if {[lindex $values 3]} {return}
set itemStr [string trim [lindex $values 0]]
set listtype [lindex $values 1]
if {![string length $itemStr]} {
beep
message "You must give a string which each item begins with."
return
}
set startPos [getPos]
set endPos [selEnd]
if {[catch {search -s -f 1 -i 0 -r 0 -m 0 -- $itemStr $startPos} res] || \
[lindex $res 1] > $endPos} {
beep
message "No list item in selection."
return
}
# Check that the selections begins with a list item.
set preText [getText $startPos [lindex $res 0]]
if {![is::Whitespace $preText]} {
beep
message "There is some text before the first list item."
return
}
set indent [htmlFindNextIndent]
set liIndent $indent
if {$listtype != "None" && $HTMLmodeVars(indent${listtype})} {set liIndent [htmlIncreaseIndent $liIndent]}
if {$listtype != "None"} {
set text "[htmlOpenCR $indent 1]"
if {[string index $text 0] == "\r"} {set text "${liIndent}$text"}
append text "<[htmlSetCase $listtype]>\r"
} else {
set text ""
set preInd [htmlOpenCR $indent]
if {[regexp "\r" $preInd]} {set text $preInd}
}
# Get each list item.
set startPos [lindex $res 1]
while {![catch {search -s -f 1 -i 0 -r 0 -m 0 -- $itemStr $startPos} res2] && \
[lindex $res2 1] <= $endPos} {
set text2 [string trim [getText $startPos [lindex $res2 0]]]
if {$listtype != "None" && $HTMLmodeVars(indent${listtype})} {htmlIndentChunk text2}
append text "$liIndent<[htmlSetCase LI]>$text2"
if {$isContainer} {append text [htmlCloseElem LI]}
append text "\r"
set startPos [lindex $res2 1]
}
set text2 [string trim [getText $startPos $endPos]]
if {$listtype != "None" && $HTMLmodeVars(indent${listtype})} {htmlIndentChunk text2}
append text "$liIndent<[htmlSetCase LI]>$text2"
if {$isContainer} {append text [htmlCloseElem LI]}
append text "\r"
if {$listtype != "None"} {append text $indent [htmlCloseElem $listtype] [htmlCloseCR2 $indent [selEnd]]}
replaceText [getPos] [selEnd] $text
}
# Discursive Lists (term and description elems)
#
# The selection becomes the *description* (*not* the term)
# Build a discursive list
proc htmlDiscursive {} {
global htmlCurSel
global htmlIsSel
global HTMLmodeVars elecStopMarker
set containers $HTMLmodeVars(lidtAreContainers)
set useTabMarks $HTMLmodeVars(useTabMarks)
set listStr [htmlListQuestions DL DT "DT and DD"]
if {![llength $listStr]} {
return
} else {
set dlEntries [lindex $listStr 0]
set askForLiAttr [lindex $listStr 1]
}
if {$askForLiAttr} {
set openDD {htmlOpenElem DD "" 0}
set openDT {htmlOpenElem DT "" 0}
} else {
set openDD {htmlSetCase <DD>}
set openDT {htmlSetCase <DT>}
}
htmlGetSel
set Sel $htmlCurSel
set indent [htmlFindNextIndent]
set exind $indent
set text [htmlOpenCR $indent 1]
if {$HTMLmodeVars(indentDL)} {
set exind [htmlIncreaseIndent $exind]
htmlIndentChunk Sel
}
if {$containers} {
if {[set text1 "[htmlOpenElem DL "" 0]\r"] == "\r"} {return}
append text $text1
# the first entry
if {[set text1 [eval $openDT]] == ""} {return}
append text $exind $text1
set currpos [expr [getPos] + [string length $text]]
append text "[htmlCloseElem DT]\t"
if {[set text1 [eval $openDD]] == ""} {return}
append text $text1
if {$htmlIsSel} {
append text $Sel
} elseif {$useTabMarks} {
append text $elecStopMarker
}
append text [htmlCloseElem DD]
# the rest of the entries
for {set i 1} {$i < $dlEntries} {incr i} {
append text "\r"
if {[set text1 [eval $openDT]] == ""} {return}
append text $exind $text1
if {$useTabMarks} { append text $elecStopMarker }
append text [htmlCloseElem DT] "\t"
if {[set text1 [eval $openDD]] == ""} {return}
append text $text1
if {$useTabMarks} { append text $elecStopMarker }
append text [htmlCloseElem DD]
}
if {$useTabMarks} {append text $elecStopMarker}
} else {
if {[set text1 [htmlOpenElem DL "" 0]] == ""} {return}
append text $text1
append text "\r"
# The first entry
if {[set text1 [eval $openDT]] == ""} {return}
append text $exind $text1
set currpos [expr [getPos] + [string length $text]]
append text "\t"
if {[set text1 [eval $openDD]] == ""} {return}
append text $text1
if {$htmlIsSel} {
append text $Sel
}
if {$useTabMarks} {append text $elecStopMarker}
# Now for the rest of the entries
for {set i 1} {$i < $dlEntries} {incr i} {
append text "\r"
if {[set text1 [eval $openDT]] == ""} {return}
append text $exind $text1
if {$useTabMarks} {append text $elecStopMarker}
append text "\t"
if {[set text1 [eval $openDD]] == ""} {return}
append text $text1
if {$useTabMarks} {append text $elecStopMarker}
}
}
append text "\r$indent[htmlCloseElem DL]"
append text [htmlCloseCR2 $indent [getPos]]
if {$useTabMarks} {append text $elecStopMarker}
if {$htmlIsSel} { deleteSelection }
insertText $text
goto $currpos
}
# Add an individual entry to a discursive list
proc htmlNewDiscursiveEntry {} {
global htmlCurSel htmlIsSel
global HTMLmodeVars elecStopMarker
# Is in STYLE container?
if {[htmlIsInContainer STYLE]} {replaceText [getPos] [selEnd] DT; return}
set useTabMarks $HTMLmodeVars(useTabMarks)
set containers $HTMLmodeVars(lidtAreContainers)
htmlGetSel
set Sel $htmlCurSel
set indent [htmlFindNextIndent]
set text [htmlOpenCR $indent]
if {$HTMLmodeVars(indentDL)} {
htmlIndentChunk Sel
}
if {$containers} {
if {[set text1 [htmlOpenElem DT "" 0]] == ""} {return}
append text $text1
set currpos [expr [getPos] + [string length $text]]
append text "[htmlCloseElem DT]\t"
if {[set text1 [htmlOpenElem DD "" 0]] == ""} {return}
append text $text1
if {$htmlIsSel} {
append text ${Sel}
} elseif {$useTabMarks} {append text $elecStopMarker}
append text [htmlCloseElem DD]
if {$useTabMarks} {append text $elecStopMarker}
if {$htmlIsSel} { deleteSelection }
insertText $text [htmlCloseCR $indent]
} else {
if {[set text1 [htmlOpenElem DT "" 0]] == ""} {return}
append text $text1
set currpos [expr [getPos] + [string length $text]]
append text "\t"
if {[set text1 [htmlOpenElem DD "" 0]] == ""} {return}
append text $text1
if {$htmlIsSel} {
append text $Sel
}
if {$useTabMarks} {append text $elecStopMarker}
if {$htmlIsSel} { deleteSelection }
insertText $text [htmlCloseCR $indent]
}
goto $currpos
}
# Different Input fields
proc htmlBuildInputElem {inputelem {cr1 0} {cr2 1}} {
global htmlElemKeyBinding
set inp2 $inputelem
if {![info exists htmlElemKeyBinding($inputelem)]} {set inp2 "INPUT TYPE=$inputelem"}
htmlBuildOpening "INPUT TYPE=\"${inputelem}\"" $cr1 $cr2 $inp2
}
# Table template. If there is any selection it is put in the first cell.
proc htmlTableTemplate {} {
global htmlCurSel htmlIsSel HTMLmodeVars elecStopMarker
set useTabMarks $HTMLmodeVars(useTabMarks)
set values {"" "" 0 0 0}
set rows ""
set cols ""
set tableOpen "<[htmlSetCase TABLE]>"
set trOpen "<[htmlSetCase TR]>"
while {1} {
set box "-t {Table template} 50 10 200 25 \
-p 50 26 150 27 \
-t {Number of rows} 10 40 150 55 -e [list [lindex $values 0]] 160 40 180 55 \
-t {Number of columns} 10 65 150 80 -e [list [lindex $values 1]] 160 65 180 80 \
-c {Table headers in first row} [lindex $values 2] 10 90 250 112 \
-c {Table headers in first column} [lindex $values 3] 10 112 250 134 \
-c {Don't insert TABLE tags} [lindex $values 4] 10 134 250 156 \
-b OK 20 250 85 270 -b Cancel 105 250 170 270\
-b {TABLE attributes…} 10 170 150 190 -b {TR attributes…} 10 200 150 220 "
set values [eval [concat dialog -w 230 -h 280 $box]]
# Cancel?
if {[lindex $values 6] } {return}
set rows [lindex $values 0]
set cols [lindex $values 1]
set THrow [lindex $values 2]
set THcol [lindex $values 3]
set table [expr ![lindex $values 4]]
if {[lindex $values 7]} {
if {!$table} {
alertnote "You have chosen not to insert TABLE tags."
} elseif {[set tmp [htmlChangeElement [string range $tableOpen 1 [expr [string length $tableOpen] - 2]] TABLE]] != ""} {
set tableOpen $tmp
}
continue
}
if {[lindex $values 8]} {
if {[set tmp [htmlChangeElement [string range $trOpen 1 [expr [string length $trOpen] - 2]] TR]] != ""} {
set trOpen $tmp
}
continue
}
if {![is::PositiveInteger $rows] || ![is::PositiveInteger $cols] } {
alertnote "The number of rows and columns must be specified."
} else {
break
}
}
htmlGetSel
if {$htmlIsSel} {deleteSelection}
set indent [htmlFindNextIndent]
set trIndent $indent
if {$HTMLmodeVars(indentTABLE) && $table} {set trIndent [htmlIncreaseIndent $trIndent]}
set tdIndent $trIndent
if {$HTMLmodeVars(indentTR)} {set tdIndent [htmlIncreaseIndent $tdIndent]}
set text [htmlOpenCR $indent 1]
if {$table} {append text "\r" $indent $tableOpen "\r$trIndent"}
for {set i 1} {$i <= $rows} {incr i} {
if {$i > 1 || $table} {append text "\r$trIndent"}
append text "$trOpen\r$tdIndent"
for {set j 1} {$j <= $cols} {incr j} {
# Put TH in first row or column?
if {$i == 1 && $THrow || $j == 1 && $THcol} {
set cell [htmlSetCase TH]
} else {
set cell [htmlSetCase TD]
}
append text "<$cell>"
if {$i == 1 && $j == 1} {
if {$htmlIsSel} {
append text $htmlCurSel
} else {
set curPos [expr [getPos] + [string length $text]]
}
} elseif {$htmlIsSel && ( $i == 1 && $j == 2 || $i == 2 && $cols == 1 )} {
set curPos [expr [getPos] + [string length $text]]
} elseif {$useTabMarks} {
append text $elecStopMarker
}
append text [htmlCloseElem $cell]
}
append text "\r$trIndent[htmlCloseElem TR]\r$trIndent"
}
if {$table} {append text "\r$indent[htmlCloseElem TABLE][htmlCloseCR2 $indent [getPos]]"}
if {$useTabMarks && ($rows > 1 || $cols > 1 || !$htmlIsSel)} {append text $elecStopMarker}
insertText $text
goto $curPos
}
# Take table rows in a selection and remove the TR, TD and TH elements and
# put tabs between the elements.
proc htmlRowstoTabs {} {
if {![isSelection]} {
beep
message "No selection."
return
}
set startPos [getPos]
set endPos [selEnd]
if {[catch {search -s -f 1 -i 1 -r 1 -m 0 {<TR([ \t\r]+[^>]*>|>)} $startPos} res] || \
[lindex $res 1] > $endPos} {
beep
message "No table row in selection."
return
}
# Check that the selections begins with a table row.
set preText [getText $startPos [lindex $res 0]]
if {![is::Whitespace $preText]} {
beep
message "First part of selection is not in a table row."
return
}
# Extract each table row.
set startPos [lindex $res 1]
while {![catch {search -s -f 1 -i 1 -r 1 -m 0 {<TR([ \t\r]+[^>]*>|>)} $startPos} res2] && \
[lindex $res2 1] <= $endPos} {
set text2 [getText $startPos [lindex $res2 0]]
regsub -all "\[\t\r\]+" $text2 " " text2
append text [string trim $text2] "\r"
set startPos [lindex $res2 1]
}
set text2 [getText $startPos $endPos]
regsub -all "\[\t\r\]+" $text2 " " text2
append text [string trim $text2]
# Check that there is nothing after the last table row.
if {![catch {search -s -f 1 -i 1 -r 1 -m 0 {</TR>} $startPos} res] \
&& [lindex $res 1] <= $endPos} {
set preText [getText [lindex $res 1] $endPos]
if {![is::Whitespace $preText]} {
beep
message "Last part of selection not in a table row."
return
}
}
# Make the transformation.
foreach ln [split $text "\r"] {
if {![string length $ln]} continue
regsub -all {> +<} $ln "><" ln
regsub -all {<(t|T)(h|H|d|D)([ ]+[^>]*>|>)} $ln "\t" ln
regsub { } $ln "" ln
regsub -all {</(t|T)(h|H|d|D|r|R)>} $ln "" ln
append out "$ln\r"
}
replaceText [getPos] [selEnd] $out
}
# Convert tab-delimited format to table rows.
# First row and first coloumn can optionally consist of table headers.
proc htmlImportTable {} {htmlTabstoRows file}
proc htmlTabstoRows {{where selection}} {
global HTMLmodeVars
if {$where == "selection"} {
if {![isSelection]} {
beep
message "No selection."
return
}
set tabtext [string trim [getSelect]]
set newln "\r"
set htext "Tabs to Rows"
} else {
set fil [getfile "Select file with table."]
if {![htmlIsTextFile $fil alertnote]} {return}
set fid [open $fil r]
set tabtext [string trim [read $fid]]
close $fid
if {[regexp {\n} $tabtext]} {
set newln "\n"
} else {
set newln "\r"
}
regsub -all "\n\r" $tabtext "\n" tabtext
set htext "Import table"
}
set values {0 0 0 0}
set tableOpen "<[htmlSetCase TABLE]>"
set trOpen "<[htmlSetCase TR]>"
while {1} {
set box "-t [list $htext] 50 10 200 25 \
-p 50 26 150 27 \
-c {Table headers in first row} [lindex $values 0] 10 40 250 62 \
-c {Table headers in first column} [lindex $values 1] 10 62 250 84 \
-c {Don't insert TABLE tags} [lindex $values 2] 10 84 250 106 \
-c {Treat multiple tabs as one} [lindex $values 3] 10 106 250 128 \
-b OK 20 220 85 240 -b Cancel 105 220 170 240\
-b {TABLE attributes…} 10 140 150 160 -b {TR attributes…} 10 170 150 190 "
set values [eval [concat dialog -w 230 -h 250 $box]]
# Cancel?
if {[lindex $values 5] } {return}
set THrow [lindex $values 0]
set THcol [lindex $values 1]
set table [expr ![lindex $values 2]]
if {[lindex $values 3]} {
set tabexp "\t+"
} else {
set tabexp \t
}
if {[lindex $values 6]} {
if {!$table} {
alertnote "You have chosen not to insert TABLE tags."
} elseif {[set tmp [htmlChangeElement [string range $tableOpen 1 [expr [string length $tableOpen] - 2]] TABLE]] != ""} {
set tableOpen $tmp
}
continue
}
if {[lindex $values 7]} {
if {[set tmp [htmlChangeElement [string range $trOpen 1 [expr [string length $trOpen] - 2]] TR]] != ""} {
set trOpen $tmp
}
continue
}
break
}
set oelem "${trOpen}\r"
if {$oelem == "\r"} {return}
set trIndent ""
if {$HTMLmodeVars(indentTABLE) && $table} {set trIndent [htmlIncreaseIndent $trIndent]}
set tdIndent $trIndent
if {$HTMLmodeVars(indentTR)} {set tdIndent [htmlIncreaseIndent $tdIndent]}
set out [htmlOpenCR "" 1]
if {$table} {append out "\r" $tableOpen "\r"}
set i 1
foreach ln [split $tabtext $newln] {
if {![string length $ln]} {
append out "$trIndent$oelem$trIndent[htmlCloseElem TR]\r"
} else {
# Should there be headers in the first row?
if {$i == 1 && $THrow} {
set cell TH
} else {
set cell TD
}
# Should there be headers in the first column?
if {$THcol || ($i == 1 && $THrow)} {
set fcell TH
} else {
set fcell TD
}
regsub -all $tabexp $ln [htmlSetCase "</$cell><$cell>"] ln
if {$THcol} {
regsub {[tT][dDhH]} $ln [htmlSetCase TH] ln
}
if {$i > 1 || $table} {append out "$trIndent\r"}
append out "$trIndent$oelem$tdIndent<[htmlSetCase $fcell]>$ln"
# Add cell or fcell closing, depending on if there is more than one cell.
if {![regexp [htmlCloseElem $fcell] $ln]} {
append out [htmlCloseElem $fcell]
} else {
append out [htmlCloseElem $cell]
}
append out "\r$trIndent[htmlCloseElem TR]\r"
}
incr i
}
set indent [htmlFindNextIndent]
if {$table} {
append out "$trIndent\r[htmlCloseElem TABLE]"
append out [htmlCloseCR2 "" [selEnd]]
}
if {$indent != ""} {htmlIndentChunk out $indent}
set out $indent[string trimright $out " \t"]
if {$where == "selection"} {
replaceText [getPos] [selEnd] $out
} else {
insertText $out
}
}
# Converts an NCSA or CERN image map file to a client side image map.
proc htmlConvertNCSAMap {} {htmlConvertMap NCSA}
proc htmlConvertCERNMap {} {htmlConvertMap CERN}
proc htmlConvertMap {type} {
global HTMLmodeVars
if {[catch {getfile "Select the $type image map file."} fil] || ![htmlIsTextFile $fil alertnote] ||
[catch {open $fil r} fid]} {return}
set filecont [read $fid]
close $fid
if {[regexp {\n} $filecont]} {
set newln "\n"
} else {
set newln "\r"
}
set area [html${type}map [split $filecont $newln]]
set text [lindex $area 2]
if {![string length $text]} {
alertnote "No image map found in [file tail $fil]."
return
} elseif {[lindex $area 1]} {
if {[askyesno "Some lines in [file tail $fil] have invalid syntax. They are ignored. Continue?"] == "no"} {return}
} elseif {[lindex $area 0]} {
if {[askyesno "Some lines in [file tail $fil] specify a shape not supported. They are ignored. Continue?"] == "no"} {return}
}
if {![string length [set map [htmlOpenElem MAP "" 0]]]} {return}
set aind [set indent [htmlFindNextIndent]]
if {$HTMLmodeVars(indentMAP)} {set aind [htmlIncreaseIndent $aind]}
regsub -all "\r" [string trimright $text] "\r$aind" text
insertText [htmlOpenCR $indent 1] $map "\r" $aind $text \r $indent [htmlCloseElem MAP] [htmlCloseCR2 $indent [getPos]]
}
proc htmlNCSAmap {lines} {
set notknown 0
set someinvalid 0
set area ""
set defarea ""
foreach l $lines {
set invalid 0
set l [string trim $l]
# Skip comments and blank lines
if {[regexp {^#} $l] || ![string length $l]} {continue}
set shape [string toupper [lindex $l 0]]
if {[lsearch {RECT CIRCLE POLY DEFAULT} $shape] < 0} {
set notknown 1
continue
}
set url [lindex $l 1]
set exp "^\[0-9\]+,\[0-9\]+$"
if {[regexp $exp $url]} {
set url ""
set cind 1
} else {
set cind 2
}
switch $shape {
RECT {
if {[regexp $exp [lindex $l $cind]] && [regexp $exp [lindex $l [expr $cind + 1]]]} {
set coord "[lindex $l $cind],[lindex $l [expr $cind + 1]]"
} else {
set invalid 1
}
}
CIRCLE {
if {[regexp $exp [lindex $l $cind] cent] && [regexp $exp [lindex $l [expr $cind + 1]] edge]} {
regexp {[0-9]+} $cent xc
regexp {[0-9]+} $edge xe
set coord "$cent,[expr $xe-$xc]"
} else {
set invalid 1
}
}
POLY {
set coord ""
foreach c [lrange $l $cind end] {
if {![regexp $exp $c]} {
set invalid 1
break
}
append coord "$c,"
}
set coord [string trimright $coord ,]
}
}
if {!$invalid} {
if {$shape == "DEFAULT"} {
set toapp defarea
} else {
set toapp area
}
append $toapp "<" [htmlSetCase "AREA SHAPE=\"$shape\""]
if {$shape != "DEFAULT"} {
append $toapp " [htmlSetCase COORDS]=\"$coord\""
}
if {[string length $url]} {
append $toapp " [htmlSetCase HREF]=\"$url\""
} else {
append $toapp " [htmlSetCase NOHREF]"
}
append $toapp ">\r"
} else {
set someinvalid 1
}
}
append area $defarea
return [list $notknown $someinvalid $area]
}
proc htmlCERNmap {lines} {
set notknown 0
set someinvalid 0
set area ""
set defarea ""
foreach l $lines {
set invalid 0
set l [string trim $l]
# Skip comments and blank lines
if {[regexp {^#} $l] || ![string length $l]} {continue}
set shape [string toupper [lindex $l 0]]
if {![string match RECT* $shape] && ![string match CIRC* $shape] &&
![string match POLY* $shape] && ![string match DEFAULT $shape]} {
set notknown 1
continue
}
set exp "^\\(\[0-9\]+,\[0-9\]+\\)$"
switch -glob $shape {
RECT* {
set url [lindex $l 3]
if {[regexp $exp [lindex $l 1]] && [regexp $exp [lindex $l 2]]} {
set coord "[string trimleft [string trimright [lindex $l 1] )] (],[string trimleft [string trimright [lindex $l 2] )] (]"
set shape RECT
} else {
set invalid 1
}
}
CIRC* {
set url [lindex $l 3]
if {[regexp $exp [lindex $l 1]] && [regexp {^[0-9]+$} [lindex $l 2]]} {
set coord "[string trimleft [string trimright [lindex $l 1] )] (],[lindex $l 2]"
set shape CIRCLE
} else {
set invalid 1
}
}
POLY* {
set coord ""
set url [lindex $l [expr [llength $l] - 1]]
if {[regexp $exp $url]} {
set url ""
set cind 1
} else {
set cind 2
}
foreach c [lrange $l 1 [expr [llength $l] - $cind]] {
if {![regexp $exp $c]} {
set invalid 1
break
}
append coord "[string trimleft [string trimright $c )] (],"
}
set coord [string trimright $coord ,]
set shape POLY
}
DEFAULT {
set url [lindex $l 1]
}
}
if {!$invalid} {
if {$shape == "DEFAULT"} {
set toapp defarea
} else {
set toapp area
}
append $toapp "<" [htmlSetCase "AREA SHAPE=\"$shape\""]
if {$shape != "DEFAULT"} {
append $toapp " [htmlSetCase COORDS]=\"$coord\""
}
if {[string length $url]} {
append $toapp " [htmlSetCase HREF]=\"$url\""
} else {
append $toapp " [htmlSetCase NOHREF]"
}
append $toapp ">\r"
} else {
set someinvalid 1
}
}
append area $defarea
return [list $notknown $someinvalid $area]
}
proc htmlComment {} {
global htmlCurSel
global htmlIsSel
global HTMLmodeVars elecStopMarker
set comStrs [htmlCommentStrings]
htmlGetSel
set text "[htmlOpenCR [set indent [htmlFindNextIndent]]][lindex $comStrs 0]$htmlCurSel"
if {$htmlIsSel} { deleteSelection }
set currpos [expr [getPos] + [string length $text]]
append text [lindex $comStrs 1] [htmlCloseCR $indent]
if {!$htmlIsSel && $HTMLmodeVars(useTabMarks)} {append text $elecStopMarker}
insertText $text
if {!$htmlIsSel} {
goto $currpos
}
}
proc htmlDocumentType {} {
set v [dialog -w 200 -h 120 -t "Document type declaration" 10 10 190 30 \
-m {Strict Strict Transitional Frameset} 10 50 190 70 -b OK 20 90 85 110 -b Cancel 105 90 170 110]
if {[lindex $v 2]} {return}
set pos [getPos]
goto 0
switch [lindex $v 0] {
Strict {set dtd {}}
Transitional {set dtd " Transitional"}
Frameset {set dtd " Frameset"}
}
set txt "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0$dtd//EN\">\n"
if {![catch {search -s -f 1 -i 0 -m 0 -r 1 {<!DOCTYPE[^<>]+>} 0} res]} {
eval deleteText $res
} else {
set res {0 0}
}
insertText $txt
goto [expr $pos + [string length $txt] - [lindex $res 1] + [lindex $res 0]]
htmlActivateHook
}
#
# Template for new file: HTML, TITLE, HEAD, BODY or FRAMESET
# Optionally input BASE, LINK, ISINDEX, META and SCRIPT in HEAD.
proc htmlNewDocument {} {htmlNewTemplate BODY}
proc htmlNewDoc.withFrames {} {htmlNewTemplate FRAMESET}
proc htmlNewTemplate {doctype} {
global htmlCurSel htmlIsSel HTMLmodeVars htmlHeadElements1 htmlHideExtensions htmlHideDeprecated elecStopMarker
set useTabMarks $HTMLmodeVars(useTabMarks)
set footers $HTMLmodeVars(footers)
set indentBODY $HTMLmodeVars(indent${doctype})
set headelems [set htmlHeadElements1]
set bodyText ""
# If the window is not empty, either new window or put text in the body.
if {![htmlIsEmptyFile]} {
set delBox [dialog -w 420 -h 90 -t "Nonempty window. Do you want to open a new window\
or put the text in the document's BODY?" 10 10 410 50 \
-b "New window" 20 60 120 80 \
-b "Put in BODY" 140 60 240 80 -b Cancel 260 60 325 80]
if {[lindex $delBox 0]} {
new -n Untitled.html -m HTML
} elseif {[lindex $delBox 2]} {
return
} else {
set bodyText "[getText 0 [maxPos]]\r"
}
}
if {$doctype == "FRAMESET"} {
set htxt "New document with frames"
} else {
set htxt "New document"
}
if {$indentBODY} {htmlIndentChunk bodyText}
# Building footer menu.
foreach f $footers {
lappend foot [file tail $f]
}
set footmenu {"No footer"}
if {[info exists foot]} {
set footmenu [concat $footmenu [lsort $foot]]
}
set docTitle ""
set inHead {0 0 ""}
foreach elem $headelems {
lappend inHead 0
}
lappend inHead "No footer" 0 1 0
while {![string length $docTitle]} {
# Construct the dialog box.
set box "-t [list $htxt] 100 10 300 25 -p 100 30 250 31 -t {TITLE} 10 40 60 55 \
-e [list [lindex $inHead 2]] 70 40 390 55 \
-t {Select the elements you want in the document\'s HEAD} 10 70 390 85"
set hpos 100
set wpos 10
set i 3
foreach elem $headelems {
append box " -c $elem [lindex $inHead $i] $wpos $hpos [expr $wpos + 100] [expr $hpos + 15]"
incr wpos 100
if {$wpos > 110} {set wpos 10; incr hpos 20}
incr i
}
if {$wpos > 10} {incr hpos 20}
incr hpos 10
append box " -t Footer 10 $hpos 80 [expr $hpos + 15] \
-m [list [concat [list [lindex $inHead $i]] $footmenu]] 90 $hpos 250 [expr $hpos + 15]"
incr hpos 30
append box " -t {Document type declaration:} 220 100 405 115"
append box " -r None [lindex $inHead [expr $i + 1]] 220 120 390 135"
if {$doctype == "BODY"} {
append box " -r Transitional [lindex $inHead [expr $i + 2]] 220 140 390 155"
append box " -r Strict [lindex $inHead [expr $i + 3]] 220 160 390 175"
} else {
append box " -r Frameset [lindex $inHead [expr $i + 2]] 220 140 390 155"
}
set inHead [eval [concat dialog -w 410 -h [expr $hpos + 30] \
-b OK 20 $hpos 85 [expr $hpos + 20] \
-b Cancel 110 $hpos 175 [expr $hpos + 20] $box]]
if {[lindex $inHead 1] } {
return
}
set docTitle [string trim [lindex $inHead 2]]
if {![string length $docTitle]} {
alertnote "A document title is required."
}
}
if {![lindex $inHead [expr $i + 1]]} {
if {$doctype == "BODY"} {
if {[lindex $inHead [expr $i + 2]]} {set dtd " Transitional"; set htmlHideExtensions 1}
if {[lindex $inHead [expr $i + 3]]} {set dtd ""; set htmlHideDeprecated 1}
} else {
set dtd " Frameset"
}
htmlSetDis
set text "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0$dtd//EN\">\n"
}
if {[set text0 [htmlOpenElem HTML "" 0]] == "" ||
[set text1 [htmlOpenElem HEAD "" 0]] == "" ||
[set text2 [htmlOpenElem TITLE "" 0]] == ""} {
return
}
append text $text0
set headIndent ""
if {$HTMLmodeVars(indentHEAD)} {set headIndent [text::Tab]}
set bodyIndent ""
if {$indentBODY} {set bodyIndent [text::Tab]}
append text "\r\r${text1}\r$headIndent\r"
append text "$headIndent${text2}${docTitle}[htmlCloseElem TITLE]\r$headIndent"
set hasScript 0
set pre(SCRIPT) "//"; set pre(STYLE) "/*"; set post(SCRIPT) ""; set post(STYLE) "*/"
for {set i 0} {$i < [llength $headelems]} {incr i} {
if {[lindex $inHead [expr $i + 3]]} {
set he [lindex $headelems $i]
if {[set text1 [htmlOpenElem $he "" 0]] != ""} {
append text "\r$headIndent${text1}"
if {$he == "SCRIPT" || $he == "STYLE"} {
append text "\r$headIndent<!-- /* Hide content from old browsers */\r$headIndent"
if {!$hasScript} {
set currpos [string length $text]
} elseif {$useTabMarks} {
append text $elecStopMarker
}
set hasScript 1
append text "\r$headIndent$pre($he) end hiding content from old browsers $post($he) -->\r$headIndent[htmlCloseElem $he]"
}
}
}
}
append text "\r$headIndent\r[htmlCloseElem HEAD]\r\r"
if {[set text1 [htmlOpenElem $doctype "" 0]] == ""} {
return
}
append text "$text1\r$bodyIndent\r$bodyIndent"
append text $bodyText
if {!$hasScript} {
set currpos [string length $text]
} elseif {$useTabMarks} {
append text $elecStopMarker
}
# Insert footer.
set footval [lindex $inHead [expr [llength $headelems] + 3]]
if {$footval != "No footer"} {
set footerFile [lindex $footers [lsearch -exact $foot $footval]]
if {![catch {readFile $footerFile} footText]} {
if {$indentBODY} {
regsub -all "\n" "[text::Tab]$footText" "\r" footText
htmlIndentChunk footText
}
append text "\r$bodyIndent\r$footText"
} else {
alertnote "Could not read footer, $footerFile"
}
}
append text "\r$bodyIndent\r[htmlCloseElem $doctype]\r\r[htmlCloseElem HTML]"
if {![htmlIsEmptyFile]} {deleteText 0 [maxPos]}
insertText $text
goto $currpos
htmlActivateHook
}
#===============================================================================
# Document index
#===============================================================================
proc htmlDocumentIndex {} {
global HTMLmodeVars
set liIndent ""
set indLists $HTMLmodeVars(indentUL)
if {$indLists} {set liIndent [text::Tab]}
if {![catch {search -s -f 1 -r 1 -m 0 -i 1 {<!--[ \t\r]+#DOCINDEX[ \t\r]+[^>]+>} 0} begin] &&
![catch {search -s -f 1 -r 1 -m 0 -i 1 {<!--[ \t\r]+/#DOCINDEX[ \t\r]+[^>]+>} [lindex $begin 1]} endind] &&
[regexp -nocase {TYPE=\"(UL|PRE,[0-9]+)\"} [getText [lindex $begin 0] [lindex $begin 1]] dum type]} {
set type [string toupper $type]
if {$type != "UL"} {
regexp {(PRE),([0-9]+)} $type dum type indent
set indStr [string range " " 1 $indent]
}
set replace 1
set mainind [htmlFindNextIndent [lindex $begin 0]]
} else {
set replace 0
set values {0 0 0 3}
set mainind [htmlFindNextIndent]
while {1} {
set box "-t {Document index} 50 10 250 30 -m {[list [lindex $values 2]] PRE UL} 10 40 60 60\
-n PRE -t Indent 70 40 120 60 -e [list [lindex $values 3]] 125 40 165 55 \
-t characters 170 40 290 60"
set values [eval [concat dialog -w 300 -h 105 -b OK 20 75 85 95 -b Cancel 110 75 175 95 $box]]
set type [lindex $values 2]
if {[lindex $values 1]} {return}
if {$type == "PRE"} {
set indent [lindex $values 3]
if {[is::PositiveInteger $indent]} {
set indStr [string range " " 1 $indent]
break
} else {
alertnote "The number of characters to indent must be specified."
}
} else {
break
}
}
}
set pos 0
set exp {<[Hh][1-6][^>]*>}
set exp2 {</[Hh][1-6]>}
set indLevel 1
set headSize 0
set toc "\r\r<[htmlSetCase $type]>"
while {![catch {search -s -f 1 -r 1 -m 0 -i 0 $exp $pos} rs] &&
![catch {search -s -f 1 -r 1 -m 0 -i 0 $exp2 [lindex $rs 1]} res]} {
set start [lindex $rs 0]
set end [lindex $res 1]
set text [getText $start $end]
set thisSize [getText [expr $start + 2] [expr $start + 3]]
set text2 [getText [lindex $rs 1] [lindex $res 0]]
regsub -all "\[\t\r\]+" $text " " text
# remove all tags from text
set headtext [string trim [htmlTagStrip $text]]
# Remove " from text.
regsub -all "\"" $headtext "" headtext
# Check if there is already an anchor
if {[regexp -nocase {<A[ \t\r\n]+[^<>]*NAME=(\"[^\">]+\"|[^ \t\n\r>]+)} $text2 dum anchor]} {
set anchor [string trim $anchor \"]
} else {
# Insert an anchor
set anchor [string trim [string range $headtext 0 15]]
# Make sure a &xxx; is not chopped.
if {[set amp [string last & $anchor]] > [set semi [string last \; $anchor]]} {
set rest [string range $headtext 16 end]
append anchor [string range $rest 0 [string first \; $rest]]
}
# Is there an <A> tag?
if {[regexp -nocase -indices {<A([ \t\r\n]+[^<>]+>|>)} $text2 atag]} {
set text3 " [htmlSetCase NAME]=\"$anchor\""
replaceText [set blah [expr [lindex $rs 1] + [lindex $atag 0] + 2]] $blah $text3
incr end [string length $text3]
} else {
set text3 "<[htmlSetCase {A NAME}]=\"$anchor\">$text2[htmlCloseElem A]"
replaceText [lindex $rs 1] [lindex $res 0] $text3
incr end [expr [string length $text3] - [string length $text2]]
}
}
if {!$headSize} {
# first header
set headSize $thisSize
} elseif {$thisSize > $headSize && $headSize} {
# new list
for {set i $headSize} {$i < $thisSize} {incr i} {
if {$type == "UL"} {
append toc "\r$liIndent\r$liIndent<[htmlSetCase UL]>"
if {$indLists} {set liIndent [htmlIncreaseIndent $liIndent]}
}
}
incr indLevel [expr $thisSize - $headSize]
set headSize $thisSize
} elseif {$thisSize < $headSize && $indLevel} {
# close a list
for {set i $thisSize} {$i < $headSize && $indLevel > 1} {incr i} {
if {$type == "UL"} {
if {$indLists} {set liIndent [htmlReduceIndent $liIndent]}
append toc "\r$liIndent[htmlCloseElem UL]\r$liIndent"
}
incr indLevel -1
}
set headSize $thisSize
}
if {$type == "UL"} {
append toc "\r$liIndent" [htmlSetCase <LI>]
} else {
append toc \r
for {set i 1} {$i < $indLevel} {incr i} {
append toc $indStr
}
}
append toc "[htmlSetCase {<A HREF}]=\"#$anchor\">$headtext[htmlCloseElem A]"
set pos $end
}
if {$type == "UL"} {
for {set i $indLevel} {$i > 0} {incr i -1} {
if {$indLists} {set liIndent [htmlReduceIndent $liIndent]}
append toc "\r$liIndent[htmlCloseElem UL]\r$liIndent"
}
} else {
append toc "\r[htmlCloseElem PRE]\r\r"
}
if {$replace} {
if {$type == "UL"} {
if {$mainind != ""} {htmlIndentChunk toc $mainind}
}
if {$pos == 0} {set toc ""}
# Find list again in case it has moved.
set begin [search -s -f 1 -r 1 -m 0 -i 1 {<!--[ \t\r]+#DOCINDEX[ \t\r]+[^>]+>} 0]
set endind [search -s -f 1 -r 1 -m 0 -i 1 {<!--[ \t\r]+/#DOCINDEX[ \t\r]+[^>]+>} [lindex $begin 1]]
replaceText [lindex $begin 1] [lindex $endind 0] [string trimright $toc] \r\r $mainind
} else {
set tt ""
if {$pos == 0} {alertnote "Empty index."; return}
if {$type == "PRE"} {
set tt ",$indent"
set ind ""
} else {
if {$mainind != ""} {htmlIndentChunk toc $mainind}
}
insertText [htmlOpenCR $mainind 1] [htmlSetCase "<!-- #DOCINDEX TYPE=\"$type$tt\" -->"] \
[string trimright $toc] \r\r $mainind [htmlSetCase "<!-- /#DOCINDEX -->"] [htmlCloseCR2 $mainind [getPos]]
}
}